{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "C1: [frozenset({1}), frozenset({2}), frozenset({3}), frozenset({4}), frozenset({5})]\n",
      "\n",
      "L1: [frozenset({5}), frozenset({2}), frozenset({3}), frozenset({1})]\n",
      "\n",
      "suppData0 {frozenset({1}): 0.5, frozenset({3}): 0.75, frozenset({4}): 0.25, frozenset({2}): 0.75, frozenset({5}): 0.75}\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "    该算法首先会生成所有单个物品的列表，接着扫描交易记录来查看哪些项集满足最小支持度的要求，\n",
    "    那些不满足最小支持度的集合会被去掉。然后对剩下的集合进行组合以生成两个元素的项集。接下来，\n",
    "    再重复扫描交易记录，去掉不满足最小支持度的项集，该过程重复，直到所有项集都被去掉\n",
    "\"\"\"\n",
    "\n",
    "# 辅助函数\n",
    "def loadDataSet():\n",
    "    return [[1,3,4],[2,3,5],[1,2,3,5],[2,5]]\n",
    "\n",
    "def createC1(dataSet):\n",
    "    C1 = []\n",
    "    for transaction in dataSet:\n",
    "        for item in transaction:\n",
    "            if [item] not in C1:\n",
    "                C1.append([item])\n",
    "    C1.sort()\n",
    "    return list(map(frozenset, C1))\n",
    "#     return map(setify, C1)\n",
    "\n",
    "def scanD(D, Ck, minSupport):\n",
    "    ssCnt = {}\n",
    "    for tid in D:\n",
    "        tid = set(tid)\n",
    "        # print(tid, list(Ck))\n",
    "        for can in Ck:\n",
    "            if can.issubset(tid):\n",
    "                if not ssCnt.get(can, 0):\n",
    "                    ssCnt[can] = 1\n",
    "                else:\n",
    "                    ssCnt[can] += 1\n",
    "    numItems = float(len(D))\n",
    "    retList = []\n",
    "    supportData ={}\n",
    "    for key in ssCnt:\n",
    "        support = ssCnt[key] / numItems\n",
    "        if support >= minSupport:\n",
    "            retList.insert(0, key)\n",
    "        supportData[key] = support\n",
    "    return retList, supportData\n",
    "\n",
    "\n",
    "dataSet = loadDataSet()\n",
    "\n",
    "C1 = createC1(dataSet)\n",
    "print(\"C1:\", C1)\n",
    "print(\"\")\n",
    "\n",
    "L1, suppData0 = scanD(dataSet, C1, 0.5)\n",
    "print(\"L1:\", L1)\n",
    "print(\"\")\n",
    "print(\"suppData0\", suppData0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[frozenset({1, 5}), frozenset({1, 2}), frozenset({1, 3}), frozenset({1})]\n"
     ]
    }
   ],
   "source": [
    "# Apriori 算法\n",
    "def aprioriGen(Lk, k):\n",
    "    retList = []\n",
    "    lenLk = len(Lk)\n",
    "    for i in range(lenLk):\n",
    "        for j in range(i+1, lenLk):\n",
    "            L1 = list(Lk[i])[:k-2]; L2 = list(Lk[j])[:k-2]\n",
    "            L1.sort(); L2.sort()\n",
    "        if L1 == L2:\n",
    "            retList.append(Lk[i] | Lk[j])\n",
    "    return retList\n",
    "\n",
    "\n",
    "print(aprioriGen([frozenset({5}), frozenset({2}), frozenset({3}), frozenset({1})], 2))\n",
    "# print(aprioriGen([frozenset({2, 3}), frozenset({3, 5}), frozenset({2, 5}), frozenset({1, 3})], 3))\n",
    "\n",
    "\n",
    "def apriori(dataSet, minSupport=0.5):\n",
    "    C1 = createC1(dataSet)\n",
    "    D = list(map(set, dataSet))\n",
    "    L1, supportData = scanD(D, C1, minSupport)\n",
    "    L = [L1]\n",
    "    k = 2\n",
    "    while (len(L[k-2]) > 2):\n",
    "        Ck = aprioriGen(L[k-2], k)\n",
    "        print(\"Ck\", Ck)\n",
    "        Lk, supK = scanD(D, Ck, minSupport)\n",
    "#         print('supportData:', supportData)\n",
    "#         print('supK:', supK)\n",
    "        supportData.update(supK)\n",
    "        L.append(Lk)\n",
    "        k += 1\n",
    "    return L, supportData\n",
    "\n",
    "\n",
    "# L, supportData = apriori(dataSet)\n",
    "# print(\"L:\", L)\n",
    "# print(\"\")\n",
    "# print(\"supportData:\", supportData)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 发现毒蘑菇的相似特征"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[frozenset({'90'}), frozenset({'86'}), frozenset({'85'}), frozenset({'36'}), frozenset({'34'})], [frozenset({'36', '34'}), frozenset({'85', '34'}), frozenset({'85', '36'}), frozenset({'86', '34'}), frozenset({'36', '86'}), frozenset({'85', '86'}), frozenset({'90', '34'}), frozenset({'36', '90'}), frozenset({'85', '90'}), frozenset({'90', '86'})], [frozenset({'90', '86', '34'}), frozenset({'85', '90', '86'}), frozenset({'36', '90', '86'}), frozenset({'85', '90', '36'}), frozenset({'85', '86', '36'}), frozenset({'85', '90', '34'}), frozenset({'85', '86', '34'}), frozenset({'85', '34', '36'}), frozenset({'36', '90', '34'}), frozenset({'36', '86', '34'})], [frozenset({'36', '86', '34', '85'}), frozenset({'36', '90', '34', '85'}), frozenset({'90', '86', '34', '36'}), frozenset({'90', '86', '34', '85'}), frozenset({'36', '90', '86', '85'})], [frozenset({'34', '36', '90', '86', '85'})]]\n",
      "\n",
      "{frozenset({'1'}): 0.48202855736090594, frozenset({'107'}): 0.1536189069423929, frozenset({'113'}): 0.04529788281634663, frozenset({'13'}): 0.2811422944362383, frozenset({'23'}): 0.4155588380108321, frozenset({'25'}): 0.03151157065484983, frozenset({'3'}): 0.4500246184145741, frozenset({'34'}): 0.9741506646971935, frozenset({'36'}): 0.8385032003938946, frozenset({'38'}): 0.30920728705071393, frozenset({'40'}): 0.050221565731166914, frozenset({'52'}): 0.4327917282127031, frozenset({'54'}): 0.137863121614968, frozenset({'59'}): 0.637124569177745, frozenset({'63'}): 0.6075824716888233, frozenset({'67'}): 0.5494830132939439, frozenset({'76'}): 0.5396356474643033, frozenset({'85'}): 1.0, frozenset({'86'}): 0.9753815854258986, frozenset({'9'}): 0.31462333825701627, frozenset({'90'}): 0.9217134416543574, frozenset({'93'}): 0.48842934515017233, frozenset({'98'}): 0.23042836041358936, frozenset({'108'}): 0.049236829148202856, frozenset({'114'}): 0.26440177252584934, frozenset({'14'}): 0.13195470211718366, frozenset({'2'}): 0.517971442639094, frozenset({'26'}): 0.049236829148202856, frozenset({'39'}): 0.690792712949286, frozenset({'55'}): 0.06843919251600197, frozenset({'99'}): 0.24224519940915806, frozenset({'115'}): 0.035942885278188084, frozenset({'15'}): 0.12801575578532742, frozenset({'27'}): 0.049236829148202856, frozenset({'4'}): 0.05563761693746923, frozenset({'41'}): 0.12900049236829148, frozenset({'10'}): 0.3993106843919252, frozenset({'109'}): 0.047267355982274745, frozenset({'16'}): 0.22648941408173315, frozenset({'24'}): 0.5844411619891678, frozenset({'28'}): 0.4342688330871492, frozenset({'37'}): 0.16149679960610536, frozenset({'53'}): 0.5672082717872969, frozenset({'94'}): 0.3417035942885278, frozenset({'42'}): 0.09256523879862137, frozenset({'110'}): 0.49729197439684886, frozenset({'43'}): 0.18365337272279667, frozenset({'44'}): 0.1479566715903496, frozenset({'11'}): 0.28557360905957657, frozenset({'64'}): 0.07385524372230429, frozenset({'111'}): 0.21073362875430823, frozenset({'5'}): 0.003938946331856229, frozenset({'6'}): 0.3879862136878385, frozenset({'116'}): 0.38749384539635645, frozenset({'56'}): 0.464795667159035, frozenset({'117'}): 0.14081733136386015, frozenset({'57'}): 0.023633677991137372, frozenset({'65'}): 0.034958148695224026, frozenset({'100'}): 0.005908419497784343, frozenset({'60'}): 0.06794682422451995, frozenset({'45'}): 0.09010339734121123, frozenset({'68'}): 0.07090103397341212, frozenset({'77'}): 0.23042836041358936, frozenset({'69'}): 0.23042836041358936, frozenset({'78'}): 0.07090103397341212, frozenset({'46'}): 0.060561299852289516, frozenset({'17'}): 0.18463810930576072, frozenset({'101'}): 0.20088626292466766, frozenset({'29'}): 0.2658788774002954, frozenset({'61'}): 0.2919743968488429, frozenset({'66'}): 0.28360413589364847, frozenset({'70'}): 0.055145248645987195, frozenset({'79'}): 0.053175775480059084, frozenset({'95'}): 0.15952732644017725, frozenset({'71'}): 0.053175775480059084, frozenset({'18'}): 0.01772525849335303, frozenset({'30'}): 0.023633677991137372, frozenset({'80'}): 0.06302314130969966, frozenset({'102'}): 0.29394387001477107, frozenset({'112'}): 0.041851304775972424, frozenset({'118'}): 0.023633677991137372, frozenset({'19'}): 0.0206794682422452, frozenset({'47'}): 0.011816838995568686, frozenset({'58'}): 0.3052683407188577, frozenset({'72'}): 0.011816838995568686, frozenset({'91'}): 0.07385524372230429, frozenset({'31'}): 0.07090103397341212, frozenset({'48'}): 0.21270310192023634, frozenset({'20'}): 0.0019694731659281144, frozenset({'96'}): 0.005908419497784343, frozenset({'119'}): 0.10241260462826195, frozenset({'103'}): 0.008862629246676515, frozenset({'21'}): 0.0054160512063023145, frozenset({'7'}): 0.1019202363367799, frozenset({'81'}): 0.011816838995568686, frozenset({'22'}): 0.0019694731659281144, frozenset({'32'}): 0.07090103397341212, frozenset({'82'}): 0.0029542097488921715, frozenset({'12'}): 0.0004923682914820286, frozenset({'8'}): 0.0004923682914820286, frozenset({'49'}): 0.0029542097488921715, frozenset({'35'}): 0.0258493353028065, frozenset({'50'}): 0.010585918266863614, frozenset({'73'}): 0.023633677991137372, frozenset({'83'}): 0.023633677991137372, frozenset({'87'}): 0.011816838995568686, frozenset({'51'}): 0.007877892663712457, frozenset({'104'}): 0.005908419497784343, frozenset({'88'}): 0.011816838995568686, frozenset({'33'}): 0.004431314623338257, frozenset({'74'}): 0.004431314623338257, frozenset({'84'}): 0.004431314623338257, frozenset({'92'}): 0.004431314623338257, frozenset({'97'}): 0.004431314623338257, frozenset({'105'}): 0.005908419497784343, frozenset({'106'}): 0.005908419497784343, frozenset({'62'}): 0.0029542097488921715, frozenset({'75'}): 0.0009847365829640572, frozenset({'89'}): 0.0009847365829640572, frozenset({'90', '86'}): 0.897095027080256, frozenset({'85', '90'}): 0.9217134416543574, frozenset({'36', '90'}): 0.7956671590349581, frozenset({'90', '34'}): 0.8980797636632201, frozenset({'85', '86'}): 0.9753815854258986, frozenset({'36', '86'}): 0.8148695224027572, frozenset({'86', '34'}): 0.9731659281142294, frozenset({'85', '36'}): 0.8385032003938946, frozenset({'85', '34'}): 0.9741506646971935, frozenset({'36', '34'}): 0.8126538650910882, frozenset({'36', '86', '34'}): 0.8126538650910882, frozenset({'36', '90', '34'}): 0.7720334810438207, frozenset({'85', '34', '36'}): 0.8126538650910882, frozenset({'85', '86', '34'}): 0.9731659281142294, frozenset({'85', '90', '34'}): 0.8980797636632201, frozenset({'85', '86', '36'}): 0.8148695224027572, frozenset({'85', '90', '36'}): 0.7956671590349581, frozenset({'36', '90', '86'}): 0.7720334810438207, frozenset({'85', '90', '86'}): 0.897095027080256, frozenset({'90', '86', '34'}): 0.897095027080256, frozenset({'36', '90', '86', '85'}): 0.7720334810438207, frozenset({'90', '86', '34', '85'}): 0.897095027080256, frozenset({'90', '86', '34', '36'}): 0.7720334810438207, frozenset({'36', '90', '34', '85'}): 0.7720334810438207, frozenset({'36', '86', '34', '85'}): 0.8126538650910882, frozenset({'34', '36', '90', '86', '85'}): 0.7720334810438207}\n"
     ]
    }
   ],
   "source": [
    "mushDataSet = [line.split() for line in open('mushroom.dat').readlines()]\n",
    "mushDataSet\n",
    "L, supportData = apriori(mushDataSet, minSupport=0.7)\n",
    "print(L)\n",
    "print(\"\")\n",
    "print(supportData)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[frozenset({2}), frozenset({3})]\n",
      "[frozenset({3}), frozenset({5})]\n",
      "[frozenset({2}), frozenset({5})]\n",
      "frozenset({5}) --> frozenset({2}) conf: 1.0\n",
      "frozenset({2}) --> frozenset({5}) conf: 1.0\n",
      "[frozenset({1}), frozenset({3})]\n",
      "frozenset({1}) --> frozenset({3}) conf: 1.0\n",
      "[frozenset({2}), frozenset({3}), frozenset({5})]\n",
      "H= [frozenset({2}), frozenset({3}), frozenset({5})]\n",
      "H[0]= frozenset({2})\n",
      "len(freqSet)= 3\n",
      "Hmp1= [frozenset({2, 3}), frozenset({2, 5}), frozenset({3, 5})]\n",
      "Hmp1= []\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[(frozenset({5}), frozenset({2}), 1.0),\n",
       " (frozenset({2}), frozenset({5}), 1.0),\n",
       " (frozenset({1}), frozenset({3}), 1.0)]"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def generateRules(L, supportData, minConf=0.7):\n",
    "    \"\"\"\n",
    "    函数说明：关联规则生成函数\n",
    "    频繁项集列表：L\n",
    "    包含那些频繁项集支持数据的字典：supportData\n",
    "    最小可信度阈值：minConf\n",
    "    \"\"\"\n",
    "    bigRuleList = []           #bigRuleList是包含可信度的规则列表，此处进行初始化\n",
    "    for i in range(1, len(L)):  \n",
    "        #遍历(1, len(L))是要为L[i]提供索引值\n",
    "        #为什么要从(1, len(L))循环？\n",
    "        #注意到 L[0]是单元素项集，我们无法从单元素项集中构建关联规则；另外，L[len(L)]是空集\n",
    "        #所以，只获取有两个或者更多集合的项目\n",
    "        for freqSet in L[i]:\n",
    "            H1 = [frozenset([item]) for item in freqSet]\n",
    "            print(H1)\n",
    "            #该函数遍历L中的每一个频繁项集并对每个频繁项集创建只包含单个元素集合的列表H1\n",
    "            if (i > 1):\n",
    "            #如果频繁项集元素数目超过2,那么会考虑对它做进一步的合并\n",
    "                rulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf)\n",
    "            else:              \n",
    "                calcConf(freqSet, H1, supportData, bigRuleList, minConf)\n",
    "    return bigRuleList\n",
    " \n",
    "#\n",
    "def calcConf(freqSet, H, supportData, brl, minConf=0.7):\n",
    "    \"\"\"\n",
    "    函数说明：计算项集中只有两个元素的可信度。计算规则的可信度以及找到满足最小可信度要求的规则\n",
    "    频繁项集：freqSet\n",
    "    频繁项集中每个元素frozenset后组成的列表(可以出现在规则右部的元素列表,见234-236行):H\n",
    "    包含那些频繁项集支持数据的字典：supportData\n",
    "    包含可信度的规则列表bigRuleList：brl\n",
    "    最小可信度阈值：minConf\n",
    "    \"\"\"\n",
    "    prunedH = []                            #建立一个满足最小可信度要求的规则列表\n",
    "    for conseq in H:                        #后件，遍历 H中的所有项集并计算它们的可信度值\n",
    "        conf = supportData[freqSet]/supportData[freqSet-conseq] #可信度计算\n",
    "        if conf >= minConf:\n",
    "            print (freqSet-conseq,'-->',conseq,'conf:',conf)\n",
    "            #如果某条规则满足最小可信度值,那么将这些规则输出到屏幕显示p\n",
    "            brl.append((freqSet-conseq, conseq, conf))\n",
    "            #添加到规则里，brl是前面通过检查的bigRuleList\n",
    "            prunedH.append(conseq)          #同样需要放入列表到后面检查\n",
    "    return prunedH                          #返回一个满足最小可信度要求的规则列表\n",
    " \n",
    "#合并\n",
    "def rulesFromConseq(freqSet, H, supportData, brl, minConf=0.7):\n",
    "    \"\"\"\n",
    "    函数说明：从最初的项集中生成更多的关联规则\n",
    "    频繁项集：freqSet\n",
    "    频繁项集中每个元素frozenset后组成的列表(可以出现在规则右部的元素列表,见236-238行):H\n",
    "    包含那些频繁项集支持数据的字典：supportData\n",
    "    包含可信度的规则列表bigRuleList：brl\n",
    "    最小可信度阈值：minConf\n",
    "    \"\"\"\n",
    "    m = len(H[0])                                #计算H中的频繁项集大小m\n",
    "    print('H=',H)\n",
    "    print('H[0]=',H[0])\n",
    "    if (len(freqSet) > (m + 1)): \n",
    "        print('len(freqSet)=',len(freqSet))\n",
    "        #查看频繁项集频繁项集freqSet是否大到可以移除大小为m的子集\n",
    "        Hmp1 = aprioriGen(H, m+1)      #使用aprioriGen()来生成H中元素的无重复组合\n",
    "        print('Hmp1=',Hmp1)\n",
    "        Hmp1 = calcConf(freqSet, Hmp1, supportData, brl, minConf)   #计算可信度\n",
    "        print('Hmp1=',Hmp1)\n",
    "        if (len(Hmp1) > 1):    \n",
    "            print('len(Hmp1)=',len(Hmp1))\n",
    "            #满足最小可信度要求的规则列表多于1,则递归来判断是否可以进一步组合这些规则\n",
    "            rulesFromConseq(freqSet, Hmp1, supportData, brl, minConf)\n",
    "\n",
    "\n",
    "generateRules(L, supportData)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "frozenset({5}) --> frozenset({2}) conf: 1.0\n",
      "frozenset({2}) --> frozenset({5}) conf: 1.0\n",
      "frozenset({1}) --> frozenset({3}) conf: 1.0\n",
      "frozenset({5}) --> frozenset({2}) conf: 1.0\n",
      "frozenset({2}) --> frozenset({5}) conf: 1.0\n",
      "frozenset({1}) --> frozenset({3}) conf: 1.0\n",
      "frozenset({5}) --> frozenset({2}) conf: 1.0\n",
      "frozenset({2}) --> frozenset({5}) conf: 1.0\n",
      "frozenset({1}) --> frozenset({3}) conf: 1.0\n",
      "frozenset({5}) --> frozenset({2}) conf: 1.0\n",
      "frozenset({2}) --> frozenset({5}) conf: 1.0\n",
      "frozenset({1}) --> frozenset({3}) conf: 1.0\n"
     ]
    },
    {
     "ename": "TypeError",
     "evalue": "object of type 'NoneType' has no len()",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-56-7d073c7f5fdd>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m     32\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     33\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 34\u001b[1;33m \u001b[0mrules\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgenerateRules\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mL\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msupportData\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     35\u001b[0m \u001b[0mrules\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m<ipython-input-56-7d073c7f5fdd>\u001b[0m in \u001b[0;36mgenerateRules\u001b[1;34m(L, supportData, minConf)\u001b[0m\n\u001b[0;32m      7\u001b[0m                 \u001b[0mH1\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[0mfrozenset\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mitem\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mitem\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mfreqSet\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      8\u001b[0m                 \u001b[1;32mif\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m>\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 9\u001b[1;33m                     \u001b[0mrulesFromConseq\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfreqSet\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mH1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msupportData\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbigRuleList\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mminConf\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     10\u001b[0m                 \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     11\u001b[0m                     \u001b[0mcalcConf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfreqSet\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mH1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msupportData\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbigRuleList\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mminConf\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m<ipython-input-56-7d073c7f5fdd>\u001b[0m in \u001b[0;36mrulesFromConseq\u001b[1;34m(freqSet, H, supportData, brl, minConf)\u001b[0m\n\u001b[0;32m     28\u001b[0m         \u001b[0mHmp1\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0maprioriGen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mH\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mm\u001b[0m\u001b[1;33m+\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     29\u001b[0m         \u001b[0mHmp1\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcalcConf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfreqSet\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mHmp1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msupportData\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbrl\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mminConf\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 30\u001b[1;33m         \u001b[1;32mif\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mHmp1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m>\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     31\u001b[0m             \u001b[0mrulesFromConseq\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfreqSet\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mHmp1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msupportData\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbrl\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mminConf\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     32\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mTypeError\u001b[0m: object of type 'NoneType' has no len()"
     ]
    }
   ],
   "source": [
    "# 关系规则生成函数\n",
    "def generateRules(L, supportData, minConf=0.7):\n",
    "    bigRuleList = []\n",
    "    for i in range(1, len(L)):\n",
    "        for freqSet in L[i]:\n",
    "            for freqSet in L[i]:\n",
    "                H1 = [frozenset([item]) for item in freqSet]\n",
    "                if (i>1):\n",
    "                    rulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf)\n",
    "                else:\n",
    "                    calcConf(freqSet, H1, supportData, bigRuleList, minConf)\n",
    "    return bigRuleList\n",
    "\n",
    "\n",
    "def calcConf(freqSet, H, supportData, brl, minConf):\n",
    "    prunedH = []\n",
    "    for conseq in H:\n",
    "        conf = supportData[freqSet] / supportData[freqSet - conseq]\n",
    "        if conf >= minConf:\n",
    "            print(freqSet-conseq, '-->', conseq, 'conf:', conf)\n",
    "            brl.append((freqSet-conseq, conseq, conf))\n",
    "            prunedH.append(conseq)\n",
    "            \n",
    "            \n",
    "def rulesFromConseq(freqSet, H, supportData, brl, minConf=0.7):\n",
    "    m = len(H[0])\n",
    "    if (len(freqSet) > (m+1)):\n",
    "        Hmp1 = aprioriGen(H, m+1)\n",
    "        Hmp1 = calcConf(freqSet, Hmp1, supportData, brl, minConf)\n",
    "        if (len(Hmp1)>1):\n",
    "            rulesFromConseq(freqSet, Hmp1, supportData, brl, minConf)\n",
    "            \n",
    "    \n",
    "rules = generateRules(L, supportData)\n",
    "rules"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
